using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Logging;
using System.ComponentModel.DataAnnotations;
using Lzfy_His_Service.Services;
using Lzfy_His_Service.Models;
using Lzfy_His_Service.Models.Configuration;
using Lzfy_His_Service.Exceptions;
using Lzfy_His_Service.Logging;
using Senparc.Weixin.Work.AdvancedAPIs.OAuth2;

namespace Lzfy_His_Service.Controllers
{
    /// <summary>
    /// Senparc企业微信控制器
    /// </summary>
    [ApiController]
    [Route("api/senparc-wechat")]
    [Produces("application/json")]
    public class SenparcWeChatController : ControllerBase
    {
        private readonly ISenparcWeChatService _senparcWeChatService;
        private readonly IAuthService _authService;
        private readonly ILogger<SenparcWeChatController> _logger;
        private readonly SenparcWeChatConfiguration _config;

        public SenparcWeChatController(
            ISenparcWeChatService senparcWeChatService,
            IAuthService authService,
            ILogger<SenparcWeChatController> logger,
            IOptions<SenparcWeChatConfiguration> config)
        {
            _senparcWeChatService = senparcWeChatService ?? throw new ArgumentNullException(nameof(senparcWeChatService));
            _authService = authService ?? throw new ArgumentNullException(nameof(authService));
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
            _config = config.Value ?? throw new ArgumentNullException(nameof(config));
        }

        /// <summary>
        /// 获取企业微信授权URL
        /// </summary>
        /// <param name="request">授权URL请求</param>
        /// <returns>授权URL响应</returns>
        [HttpGet("auth-url")]
        [AllowAnonymous]
        [ProducesResponseType(typeof(AuthUrlResponse), 200)]
        [ProducesResponseType(typeof(ErrorResponse), 400)]
        [ProducesResponseType(typeof(ErrorResponse), 500)]
        public async Task<ActionResult<AuthUrlResponse>> GetAuthUrl([FromQuery] AuthUrlRequest request)
        {
            try
            {
                if (!_config.Enabled)
                {
                    return BadRequest(new ErrorResponse
                    {
                        Code = "WECHAT_DISABLED",
                        Message = "企业微信登录功能已禁用"
                    });
                }

                var authUrl = await _senparcWeChatService.GetAuthUrlAsync(request.RedirectUri, request.State);
                
                var response = new AuthUrlResponse
                {
                    AuthUrl = authUrl,
                    State = request.State ?? Guid.NewGuid().ToString("N")[..16],
                    RedirectUri = request.RedirectUri ?? _config.RedirectUri,
                    ExpiresAt = DateTime.UtcNow.AddMinutes(10) // 授权URL 10分钟有效
                };

                _logger.LogInformation("生成企业微信授权URL成功，客户端IP：{ClientIP}", GetClientIpAddress());

                return Ok(response);
            }
            catch (WeChatConfigException ex)
            {
                _logger.LogWarning("企业微信配置错误：{ErrorCode} - {ErrorMessage}", ex.ErrorCode, ex.ErrorMessage);
                return BadRequest(new ErrorResponse
                {
                    Code = ex.ErrorCode,
                    Message = ex.ErrorMessage
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取企业微信授权URL失败");
                return StatusCode(500, new ErrorResponse
                {
                    Code = "INTERNAL_ERROR",
                    Message = "获取授权URL失败"
                });
            }
        }

        /// <summary>
        /// 企业微信登录
        /// </summary>
        /// <param name="request">登录请求</param>
        /// <returns>登录响应</returns>
        [HttpPost("login")]
        [AllowAnonymous]
        [ProducesResponseType(typeof(LoginResponse), 200)]
        [ProducesResponseType(typeof(ErrorResponse), 400)]
        [ProducesResponseType(typeof(ErrorResponse), 401)]
        [ProducesResponseType(typeof(ErrorResponse), 500)]
        public async Task<ActionResult<LoginResponse>> Login([FromBody] SenparcWeChatLoginRequest request)
        {
            var clientIp = GetClientIpAddress();
            
            try
            {
                if (!_config.Enabled)
                {
                    return BadRequest(new ErrorResponse
                    {
                        Code = "WECHAT_DISABLED",
                        Message = "企业微信登录功能已禁用"
                    });
                }

                // 验证请求参数
                if (!ModelState.IsValid)
                {
                    var errors = ModelState.Values.SelectMany(v => v.Errors).Select(e => e.ErrorMessage);
                    return BadRequest(new ErrorResponse
                    {
                        Code = "INVALID_REQUEST",
                        Message = string.Join("; ", errors)
                    });
                }

                // 通过授权码获取用户信息
                var userInfoResult = await _senparcWeChatService.GetUserInfoAsync(request.Code);
                
                if (string.IsNullOrEmpty(userInfoResult.UserId))
                {
                    _logger.LogLoginFailed("获取用户信息失败", clientIp);
                    return Unauthorized(new ErrorResponse
                    {
                        Code = "USER_INFO_FAILED",
                        Message = "获取用户信息失败"
                    });
                }

                // 获取成员详细信息
                var memberInfo = await _senparcWeChatService.GetMemberInfoAsync(userInfoResult.UserId);
                
                // 构建用户登录信息
                var loginInfo = new UserLoginInfo
                {
                    UserId = userInfoResult.UserId,
                    UserName = memberInfo.name ?? userInfoResult.name ?? "未知用户",
                    Mobile = memberInfo.mobile,
                    Email = memberInfo.email,
                    Department = memberInfo.department,
                    Position = memberInfo.position,
                    Avatar = memberInfo.avatar,
                    LoginType = "WeChat",
                    ClientIp = clientIp
                };

                // 调用现有的认证服务进行登录处理
                var loginResult = await _authService.WeChatLoginAsync(loginInfo);
                
                if (!loginResult.Success)
                {
                    _logger.LogLoginFailed(loginResult.Message, clientIp);
                    return Unauthorized(new ErrorResponse
                    {
                        Code = "LOGIN_FAILED",
                        Message = loginResult.Message
                    });
                }

                _logger.LogLoginSuccessful(userInfoResult.UserId, clientIp);

                var response = new LoginResponse
                {
                    Success = true,
                    Token = loginResult.Token,
                    RefreshToken = loginResult.RefreshToken,
                    ExpiresIn = loginResult.ExpiresIn,
                    User = new UserInfo
                    {
                        UserId = userInfoResult.UserId,
                        UserName = loginInfo.UserName,
                        Mobile = loginInfo.Mobile,
                        Email = loginInfo.Email,
                        Avatar = loginInfo.Avatar,
                        Department = loginInfo.Department,
                        Position = loginInfo.Position
                    }
                };

                return Ok(response);
            }
            catch (WeChatAuthException ex)
            {
                _logger.LogLoginFailed($"企业微信认证失败：{ex.ErrorMessage}", clientIp);
                return Unauthorized(new ErrorResponse
                {
                    Code = ex.ErrorCode,
                    Message = ex.ErrorMessage
                });
            }
            catch (WeChatApiException ex)
            {
                _logger.LogLoginFailed($"企业微信API调用失败：{ex.ErrorMessage}", clientIp);
                return StatusCode(502, new ErrorResponse
                {
                    Code = ex.ErrorCode,
                    Message = ex.ErrorMessage
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "企业微信登录失败，授权码：{Code}，客户端IP：{ClientIP}", request.Code, clientIp);
                return StatusCode(500, new ErrorResponse
                {
                    Code = "INTERNAL_ERROR",
                    Message = "登录失败，请稍后重试"
                });
            }
        }

        /// <summary>
        /// 企业微信授权回调
        /// </summary>
        /// <param name="code">授权码</param>
        /// <param name="state">状态参数</param>
        /// <returns>重定向到前端页面</returns>
        [HttpGet("callback")]
        [AllowAnonymous]
        public async Task<ActionResult> Callback([FromQuery] string code, [FromQuery] string state)
        {
            try
            {
                if (string.IsNullOrEmpty(code))
                {
                    _logger.LogWarning("企业微信回调缺少授权码，状态：{State}，客户端IP：{ClientIP}", state, GetClientIpAddress());
                    return Redirect($"{_config.FrontendErrorUrl}?error=missing_code&message=授权码缺失");
                }

                // 执行登录逻辑
                var loginRequest = new SenparcWeChatLoginRequest
                {
                    Code = code,
                    State = state
                };

                var loginResult = await Login(loginRequest);
                
                if (loginResult.Result is OkObjectResult okResult && okResult.Value is LoginResponse loginResponse)
                {
                    // 登录成功，重定向到前端成功页面，携带token
                    var successUrl = $"{_config.FrontendSuccessUrl}?token={loginResponse.Token}&refresh_token={loginResponse.RefreshToken}";
                    return Redirect(successUrl);
                }
                else
                {
                    // 登录失败，重定向到前端错误页面
                    var errorMessage = "登录失败";
                    if (loginResult.Result is ObjectResult errorResult && errorResult.Value is ErrorResponse errorResponse)
                    {
                        errorMessage = errorResponse.Message;
                    }
                    
                    return Redirect($"{_config.FrontendErrorUrl}?error=login_failed&message={Uri.EscapeDataString(errorMessage)}");
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "企业微信授权回调处理失败，授权码：{Code}，状态：{State}", code, state);
                return Redirect($"{_config.FrontendErrorUrl}?error=callback_failed&message=回调处理失败");
            }
        }

        /// <summary>
        /// 获取JS-SDK配置
        /// </summary>
        /// <param name="request">JS-SDK配置请求</param>
        /// <returns>JS-SDK配置响应</returns>
        [HttpPost("jsapi-config")]
        [AllowAnonymous]
        [ProducesResponseType(typeof(JsApiConfigResponse), 200)]
        [ProducesResponseType(typeof(ErrorResponse), 400)]
        [ProducesResponseType(typeof(ErrorResponse), 500)]
        public async Task<ActionResult<JsApiConfigResponse>> GetJsApiConfig([FromBody] JsApiConfigRequest request)
        {
            try
            {
                if (!_config.Enabled)
                {
                    return BadRequest(new ErrorResponse
                    {
                        Code = "WECHAT_DISABLED",
                        Message = "企业微信功能已禁用"
                    });
                }

                if (!ModelState.IsValid)
                {
                    var errors = ModelState.Values.SelectMany(v => v.Errors).Select(e => e.ErrorMessage);
                    return BadRequest(new ErrorResponse
                    {
                        Code = "INVALID_REQUEST",
                        Message = string.Join("; ", errors)
                    });
                }

                var jsApiConfig = await _senparcWeChatService.GetJsApiConfigAsync(request.Url);
                
                var response = new JsApiConfigResponse
                {
                    CorpId = jsApiConfig.CorpId,
                    AgentId = jsApiConfig.AgentId,
                    Timestamp = jsApiConfig.Timestamp,
                    NonceStr = jsApiConfig.NonceStr,
                    Signature = jsApiConfig.Signature,
                    JsApiList = new[]
                    {
                        "selectEnterpriseContact",
                        "openEnterpriseChat",
                        "launchMiniProgram",
                        "getContext",
                        "invoke",
                        "ready",
                        "error"
                    }
                };

                _logger.LogInformation("生成JS-SDK配置成功，URL：{Url}", request.Url);

                return Ok(response);
            }
            catch (WeChatApiException ex)
            {
                _logger.LogError("获取JS-SDK配置失败：{ErrorCode} - {ErrorMessage}", ex.ErrorCode, ex.ErrorMessage);
                return StatusCode(502, new ErrorResponse
                {
                    Code = ex.ErrorCode,
                    Message = ex.ErrorMessage
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取JS-SDK配置失败，URL：{Url}", request.Url);
                return StatusCode(500, new ErrorResponse
                {
                    Code = "INTERNAL_ERROR",
                    Message = "获取JS-SDK配置失败"
                });
            }
        }

        /// <summary>
        /// 验证企业微信签名
        /// </summary>
        /// <param name="request">签名验证请求</param>
        /// <returns>验证结果</returns>
        [HttpGet("validate")]
        [AllowAnonymous]
        [ProducesResponseType(typeof(string), 200)]
        [ProducesResponseType(typeof(ErrorResponse), 400)]
        public async Task<ActionResult> ValidateSignature([FromQuery] SignatureValidationRequest request)
        {
            try
            {
                if (!ModelState.IsValid)
                {
                    var errors = ModelState.Values.SelectMany(v => v.Errors).Select(e => e.ErrorMessage);
                    return BadRequest(new ErrorResponse
                    {
                        Code = "INVALID_REQUEST",
                        Message = string.Join("; ", errors)
                    });
                }

                var isValid = await _senparcWeChatService.ValidateSignatureAsync(
                    request.Signature, request.Timestamp, request.Nonce, request.Echostr);

                if (isValid && !string.IsNullOrEmpty(request.Echostr))
                {
                    // 验证成功，返回echostr
                    return Content(request.Echostr, "text/plain");
                }
                else if (isValid)
                {
                    // 验证成功，但没有echostr
                    return Ok(new { success = true, message = "签名验证成功" });
                }
                else
                {
                    // 验证失败
                    _logger.LogWarning("企业微信签名验证失败，签名：{Signature}", request.Signature);
                    return BadRequest(new ErrorResponse
                    {
                        Code = "SIGNATURE_INVALID",
                        Message = "签名验证失败"
                    });
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "验证企业微信签名时发生错误");
                return StatusCode(500, new ErrorResponse
                {
                    Code = "INTERNAL_ERROR",
                    Message = "签名验证失败"
                });
            }
        }

        /// <summary>
        /// 发送企业微信消息
        /// </summary>
        /// <param name="request">发送消息请求</param>
        /// <returns>发送结果</returns>
        [HttpPost("send-message")]
        [Authorize]
        [ProducesResponseType(typeof(SendMessageResponse), 200)]
        [ProducesResponseType(typeof(ErrorResponse), 400)]
        [ProducesResponseType(typeof(ErrorResponse), 401)]
        [ProducesResponseType(typeof(ErrorResponse), 500)]
        public async Task<ActionResult<SendMessageResponse>> SendMessage([FromBody] SendMessageRequest request)
        {
            try
            {
                if (!_config.Enabled)
                {
                    return BadRequest(new ErrorResponse
                    {
                        Code = "WECHAT_DISABLED",
                        Message = "企业微信功能已禁用"
                    });
                }

                if (!ModelState.IsValid)
                {
                    var errors = ModelState.Values.SelectMany(v => v.Errors).Select(e => e.ErrorMessage);
                    return BadRequest(new ErrorResponse
                    {
                        Code = "INVALID_REQUEST",
                        Message = string.Join("; ", errors)
                    });
                }

                var result = await _senparcWeChatService.SendMessageAsync(request.UserId, request.Message);
                
                var response = new SendMessageResponse
                {
                    Success = result.Success,
                    MessageId = result.MessageId,
                    ErrorCode = result.ErrorCode,
                    ErrorMessage = result.ErrorMessage
                };

                _logger.LogInformation("发送企业微信消息成功，用户：{UserId}，消息ID：{MessageId}", request.UserId, result.MessageId);

                return Ok(response);
            }
            catch (WeChatApiException ex)
            {
                _logger.LogError("发送企业微信消息失败：{ErrorCode} - {ErrorMessage}", ex.ErrorCode, ex.ErrorMessage);
                return StatusCode(502, new ErrorResponse
                {
                    Code = ex.ErrorCode,
                    Message = ex.ErrorMessage
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "发送企业微信消息失败，用户：{UserId}", request.UserId);
                return StatusCode(500, new ErrorResponse
                {
                    Code = "INTERNAL_ERROR",
                    Message = "发送消息失败"
                });
            }
        }

        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <returns>用户信息</returns>
        [HttpGet("user/{userId}")]
        [Authorize]
        [ProducesResponseType(typeof(WeChatUserInfoResponse), 200)]
        [ProducesResponseType(typeof(ErrorResponse), 400)]
        [ProducesResponseType(typeof(ErrorResponse), 404)]
        [ProducesResponseType(typeof(ErrorResponse), 500)]
        public async Task<ActionResult<WeChatUserInfoResponse>> GetUserInfo([FromRoute] string userId)
        {
            try
            {
                if (string.IsNullOrEmpty(userId))
                {
                    return BadRequest(new ErrorResponse
                    {
                        Code = "INVALID_USER_ID",
                        Message = "用户ID不能为空"
                    });
                }

                var memberInfo = await _senparcWeChatService.GetMemberInfoAsync(userId);
                
                var response = new WeChatUserInfoResponse
                {
                    UserId = memberInfo.userid,
                    Name = memberInfo.name,
                    Mobile = memberInfo.mobile,
                    Department = memberInfo.department,
                    Position = memberInfo.position,
                    Avatar = memberInfo.avatar,
                    Email = memberInfo.email
                };

                return Ok(response);
            }
            catch (WeChatApiException ex) when (ex.ErrorCode.Contains("60111") || ex.ErrorCode.Contains("60003"))
            {
                // 用户不存在
                return NotFound(new ErrorResponse
                {
                    Code = "USER_NOT_FOUND",
                    Message = "用户不存在"
                });
            }
            catch (WeChatApiException ex)
            {
                _logger.LogError("获取用户信息失败：{ErrorCode} - {ErrorMessage}", ex.ErrorCode, ex.ErrorMessage);
                return StatusCode(502, new ErrorResponse
                {
                    Code = ex.ErrorCode,
                    Message = ex.ErrorMessage
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取用户信息失败，用户ID：{UserId}", userId);
                return StatusCode(500, new ErrorResponse
                {
                    Code = "INTERNAL_ERROR",
                    Message = "获取用户信息失败"
                });
            }
        }

        #region 私有方法

        /// <summary>
        /// 获取客户端IP地址
        /// </summary>
        /// <returns>IP地址</returns>
        private string GetClientIpAddress()
        {
            var ipAddress = HttpContext.Connection.RemoteIpAddress?.ToString();
            
            // 检查是否通过代理
            if (HttpContext.Request.Headers.ContainsKey("X-Forwarded-For"))
            {
                ipAddress = HttpContext.Request.Headers["X-Forwarded-For"].FirstOrDefault()?.Split(',').FirstOrDefault()?.Trim();
            }
            else if (HttpContext.Request.Headers.ContainsKey("X-Real-IP"))
            {
                ipAddress = HttpContext.Request.Headers["X-Real-IP"].FirstOrDefault();
            }

            return ipAddress ?? "unknown";
        }

        #endregion
    }

    #region 请求和响应模型

    /// <summary>
    /// 发送消息请求
    /// </summary>
    public class SendMessageRequest
    {
        /// <summary>
        /// 用户ID
        /// </summary>
        [Required(ErrorMessage = "用户ID不能为空")]
        public string UserId { get; set; } = string.Empty;
        
        /// <summary>
        /// 消息内容
        /// </summary>
        [Required(ErrorMessage = "消息内容不能为空")]
        [StringLength(2048, ErrorMessage = "消息内容不能超过2048个字符")]
        public string Message { get; set; } = string.Empty;
    }

    /// <summary>
    /// 发送消息响应
    /// </summary>
    public class SendMessageResponse
    {
        /// <summary>
        /// 是否成功
        /// </summary>
        public bool Success { get; set; }
        
        /// <summary>
        /// 消息ID
        /// </summary>
        public string MessageId { get; set; } = string.Empty;
        
        /// <summary>
        /// 错误代码
        /// </summary>
        public string ErrorCode { get; set; } = string.Empty;
        
        /// <summary>
        /// 错误消息
        /// </summary>
        public string ErrorMessage { get; set; } = string.Empty;
    }

    /// <summary>
    /// 用户登录信息
    /// </summary>
    public class UserLoginInfo
    {
        /// <summary>
        /// 用户ID
        /// </summary>
        public string UserId { get; set; } = string.Empty;
        
        /// <summary>
        /// 用户名
        /// </summary>
        public string UserName { get; set; } = string.Empty;
        
        /// <summary>
        /// 手机号
        /// </summary>
        public string Mobile { get; set; } = string.Empty;
        
        /// <summary>
        /// 邮箱
        /// </summary>
        public string Email { get; set; } = string.Empty;
        
        /// <summary>
        /// 部门
        /// </summary>
        public int[] Department { get; set; } = Array.Empty<int>();
        
        /// <summary>
        /// 职位
        /// </summary>
        public string Position { get; set; } = string.Empty;
        
        /// <summary>
        /// 头像
        /// </summary>
        public string Avatar { get; set; } = string.Empty;
        
        /// <summary>
        /// 登录类型
        /// </summary>
        public string LoginType { get; set; } = string.Empty;
        
        /// <summary>
        /// 客户端IP
        /// </summary>
        public string ClientIp { get; set; } = string.Empty;
    }

    /// <summary>
    /// 用户信息
    /// </summary>
    public class UserInfo
    {
        /// <summary>
        /// 用户ID
        /// </summary>
        public string UserId { get; set; } = string.Empty;
        
        /// <summary>
        /// 用户名
        /// </summary>
        public string UserName { get; set; } = string.Empty;
        
        /// <summary>
        /// 手机号
        /// </summary>
        public string Mobile { get; set; } = string.Empty;
        
        /// <summary>
        /// 邮箱
        /// </summary>
        public string Email { get; set; } = string.Empty;
        
        /// <summary>
        /// 头像
        /// </summary>
        public string Avatar { get; set; } = string.Empty;
        
        /// <summary>
        /// 部门
        /// </summary>
        public int[] Department { get; set; } = Array.Empty<int>();
        
        /// <summary>
        /// 职位
        /// </summary>
        public string Position { get; set; } = string.Empty;
    }

    /// <summary>
    /// 登录响应
    /// </summary>
    public class LoginResponse
    {
        /// <summary>
        /// 是否成功
        /// </summary>
        public bool Success { get; set; }
        
        /// <summary>
        /// 访问令牌
        /// </summary>
        public string Token { get; set; } = string.Empty;
        
        /// <summary>
        /// 刷新令牌
        /// </summary>
        public string RefreshToken { get; set; } = string.Empty;
        
        /// <summary>
        /// 过期时间（秒）
        /// </summary>
        public int ExpiresIn { get; set; }
        
        /// <summary>
        /// 用户信息
        /// </summary>
        public UserInfo User { get; set; } = new();
    }

    /// <summary>
    /// 错误响应
    /// </summary>
    public class ErrorResponse
    {
        /// <summary>
        /// 错误代码
        /// </summary>
        public string Code { get; set; } = string.Empty;
        
        /// <summary>
        /// 错误消息
        /// </summary>
        public string Message { get; set; } = string.Empty;
        
        /// <summary>
        /// 详细信息
        /// </summary>
        public object? Details { get; set; }
    }

    #endregion
}